home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 2000 July / CD 3 / redhat-6.2.iso / RedHat / instimage / usr / lib / anaconda / xf86config.py < prev    next >
Encoding:
Python Source  |  2000-03-08  |  31.5 KB  |  916 lines

  1. import sys
  2. if __name__ == "__main__":
  3.     sys.path.append ('kudzu')
  4.     sys.path.append ('isys')
  5. import string
  6. import iutil
  7. import kudzu
  8. import isys
  9. import time
  10. import os
  11. from kbd import Keyboard
  12. from mouse import Mouse
  13. from translate import _
  14.  
  15. class XF86Config:
  16.     def __init__ (self, mouse = None):
  17.     self.setMouse(mouse)
  18.         self.server = None
  19.         self.vidCards = []
  20.         self.cardMan = None
  21.         self.vidRam = None
  22.         self.monEisa = None
  23.         self.monName = None
  24.         self.monHoriz = ""
  25.         self.monVert = ""
  26.     self.monSect = None
  27.         self.monID = "Generic Monitor"
  28.         self.devID = None
  29.         self.probed = 0
  30.         self.skip = 0
  31.     self.primary = 0
  32.         self.modes = { "8" :  ["640x480"] }
  33.     self.device = None
  34.         self.keyRules = "xfree86"
  35.         self.keyModel = "pc101"
  36.         self.keyLayout = "us"
  37.     kbd = Keyboard()
  38.     if kbd.type == 'Sun':
  39.         self.keyRules = "sun"
  40.         self.keyModel = kbd.model
  41.         self.keyLayout = kbd.layout
  42.         self.keyVariant = ""
  43.         self.keyOptions = ""
  44.         self.monlist = {}
  45.         self.monids = {}
  46.         
  47.     def setKeyboard (self, rules, model, layout, variant, options):
  48.         self.keyRules = rules
  49.         self.keyModel = model
  50.         self.keyLayout = layout
  51.         self.keyVariant = variant
  52.         self.keyOptions = options
  53.  
  54.     def setMouse(self, mouse):
  55.         self.mouse = mouse
  56.  
  57.     def areaCompare (self, first, second):
  58.         (sx1, sy1) = string.split (first, 'x')
  59.         (sx2, sy2) = string.split (second, 'x')
  60.  
  61.         x1 = string.atoi (sx1)
  62.         y1 = string.atoi (sy1)
  63.         x2 = string.atoi (sx2)
  64.         y2 = string.atoi (sy2)
  65.  
  66.         if ((x1 * y1) > (x2 * y2)):
  67.             return -1
  68.         elif ((x1 * y1) < (x2 * y2)):
  69.             return 1
  70.         return 0
  71.         
  72.     def filterModesByMemory (self):
  73.         if not self.vidRam:
  74.             return
  75.         if string.atoi(self.vidRam) >= 4096:
  76.             self.modes["8"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024", "1600x1200"]
  77.             self.modes["16"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024", "1600x1200"]
  78.             self.modes["32"] = ["640x480", "800x600", "1024x768", "1152x864"]
  79.         elif string.atoi(self.vidRam) >= 2048:
  80.             self.modes["8"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024"]
  81.             self.modes["16"] = ["640x480", "800x600", "1024x768", "1152x864"]
  82.             self.modes["32"] = ["640x480", "800x600"]
  83.         elif string.atoi(self.vidRam) >= 1024:
  84.             self.modes["8"] = ["640x480", "800x600", "1024x768", "1152x864"]
  85.             self.modes["16"] = ["640x480", "800x600"]
  86.             self.modes["32"] = []
  87.         elif string.atoi(self.vidRam) >= 512:
  88.             self.modes["8"] = ["640x480", "800x600"]
  89.             self.modes["16"] = ["640x480"]
  90.             self.modes["32"] = []
  91.         elif string.atoi(self.vidRam) >= 256:
  92.             self.modes["8"] = ["640x480"]
  93.  
  94.     def cards (self, thecard = None):
  95.         cards = {}
  96.         # all the straight servers
  97.         for server in [ "3DLabs", "8514", "FBDev", "I128",
  98.                         "Mach8", "Mach32", "Mach64", "Mono",
  99.                         "P9000", "S3", "S3V", "SVGA", "W32" ]:
  100.             cards["Generic " + server] = { "SERVER" : server,
  101.                                            "NAME"   : "Generic " + server }
  102.         
  103.         db = open ('/usr/X11R6/lib/X11/Cards')
  104.         lines = db.readlines ()
  105.         db.close ()
  106.         card = {}
  107.         name = None
  108.         for line in lines:
  109.             line = string.strip (line)
  110.             if not line and name:
  111.                 cards[name] = card
  112.                 card = {}
  113.                 name = None
  114.                 continue
  115.             
  116.             if line and line[0] == '#':
  117.                 continue
  118.             
  119.             if len (line) > 4 and line[0:4] == 'NAME':
  120.                 name = line[5:]
  121.                 
  122.             info = string.splitfields (line, ' ')
  123.             if card.has_key (info[0]):
  124.                 card[info[0]] = card[info[0]] + '\n' + (string.joinfields (info[1:], ' '))
  125.             else:
  126.                 card[info[0]] = string.joinfields (info[1:], ' ')
  127.  
  128.         if thecard:
  129.             card = cards[thecard]
  130.             # XXX set a max depth here to avoid infinite loops
  131.             while card.has_key ("SEE"):
  132.                 card = cards[card["SEE"]]
  133.             return card
  134.         return cards
  135.  
  136.     def monitors (self, lines = None):
  137.         if self.monlist:
  138.             return self.monlist
  139.         if not lines:
  140.             db = open ('/usr/X11R6/share/Xconfigurator/MonitorsDB')
  141.             lines = db.readlines ()
  142.             db.close ()
  143.         found = 0
  144.         for line in lines:
  145.             line = string.strip (line)
  146.             if not line:
  147.                 continue
  148.             if line and line[0] == '#':
  149.                 continue
  150.             fields = string.split (line, ';')
  151.             man = string.strip(fields[0])
  152.             model = string.strip(fields[1])
  153.             eisa = string.lower(string.strip(fields[2]))
  154.             horiz = string.strip(fields[3])
  155.             vert = string.strip(fields[4])
  156.             if self.monlist.has_key(man):
  157.                 self.monlist[man].append((model, eisa, vert, horiz))
  158.             else:
  159.                 self.monlist[man] = [(model, eisa, vert, horiz)]
  160.             self.monids[eisa] = (man, model, eisa, vert, horiz)
  161.         return self.monlist
  162.  
  163.     def setMonitor (self, (monitor, (hrange, vrange))):
  164.         self.monName = monitor
  165.         self.monID = monitor
  166.         self.monHoriz = hrange
  167.         self.monVert = vrange
  168.         
  169.     def setVidcard (self, card):
  170.         self.vidCards = [card]
  171.         self.primary = 0
  172.  
  173.         if self.vidCards:
  174.             self.devID = self.vidCards[self.primary]["NAME"]
  175.             self.server = self.vidCards[self.primary]["SERVER"]
  176.  
  177.     def probe (self, probeMonitor = 1):
  178. # XXX defer monitor probe, then re-enable this check
  179. #        if self.probed:
  180. #            return
  181.         self.probed = 1
  182.     self.device = None
  183.     self.primary = 0
  184.         # PCI probe for video cards
  185.         sections = {}
  186.  
  187.         cards = kudzu.probe (kudzu.CLASS_VIDEO,
  188.                              kudzu.BUS_UNSPEC,
  189.                              kudzu.PROBE_ALL);
  190.         
  191.         for card in cards:
  192.             section = ""
  193.             (device, server, descr) = card
  194.         if device and not self.device:
  195.         self.device = device
  196.         self.primary = len(self.vidCards)
  197.             if len (server) > 5 and server[0:5] == "Card:":
  198.                 self.vidCards.append (self.cards (server[5:]))
  199.             if len (server) > 7 and server[0:7] == "Server:":
  200.                 info = { "NAME" : "Generic " + server[7:],
  201.                          "SERVER" : server[7:] }
  202.                 self.vidCards.append (info)
  203.  
  204.         if self.vidCards:
  205.             self.devID = self.vidCards[self.primary]["NAME"]
  206.             self.server = self.vidCards[self.primary]["SERVER"]
  207.  
  208.         # VESA probe for monitor/videoram, etc.
  209.         if probeMonitor:
  210.         try:
  211.         probe = string.split (iutil.execWithCapture ("/usr/sbin/ddcprobe", ['ddcprobe']), '\n')
  212.         for line in probe:
  213.             if line and line[:9] == "OEM Name:":
  214.             self.cardMan = string.strip (line[10:])
  215.  
  216.             if line and line[:16] == "Memory installed":
  217.             memory = string.split (line, '=')
  218.             self.vidRam = string.strip (memory[2][:-2])
  219.  
  220.             if line and line[:8] == "EISA ID:":
  221.             self.monEisa = string.lower(line[9:])
  222.             self.monID = line[9:]
  223.  
  224.             if line and line[:6] == "\tName:":
  225.             if not self.monName or len (self.monName) < len (line[7:]):
  226.                 self.monName = line[7:]
  227.  
  228.             if line and line[:15] == "\tTiming ranges:":
  229.             ranges = string.split (line, ',')
  230.             self.monHoriz = string.strip (string.split (ranges[0], '=')[1])
  231.             self.monVert = string.strip (string.split (ranges[1], '=')[1])
  232.  
  233.             if self.vidCards and self.cardMan:
  234.             self.vidCards[self.primary]["VENDOR"] = self.cardMan
  235.                 if self.monEisa:
  236.                     # read the monitor DB
  237.                     self.monitors()
  238.                     if self.monids.has_key (self.monEisa):
  239.                         (man, model, eisa, vert, horiz) = self.monids[self.monEisa]
  240.                         self.monName = model
  241.                         self.monID = model
  242.                         self.monHoriz = horiz
  243.                         self.monVert = vert
  244.         except:
  245.         pass
  246.         if not self.vidRam and self.device:
  247.         if self.server and self.server[0:3] == 'Sun':
  248.             # fbconProbe gives bogus video RAM reports on SBUS and UPA servers
  249.             return
  250.         try:
  251.             (vidram, depth, mode, monitor) = isys.fbconProbe("/dev/" + self.device)
  252.             self.vidRam = "%d" % vidram
  253.             if depth:
  254.             self.modes = { "%d" % depth : [ mode ] }
  255.             self.monSect = monitor
  256.             self.bpp = "%d" % depth
  257.         except:
  258.             pass
  259.  
  260.     def probeReport (self):
  261.         probe = ""
  262.         if self.vidCards:
  263.             probe = probe + _("Video Card") + ": " + self.vidCards[self.primary]["NAME"] + "\n"
  264.             if self.vidRam:
  265.                 probe = probe + "\t" + _("Video Ram") + ": " + self.vidRam + " kb\n"
  266.         if self.server:
  267.             probe = probe + "\t" + _("X server") + ": " + self.server + "\n"
  268.         if not self.server:
  269.             probe = probe + "\t" + _("Unable to detect video card")
  270.  
  271.         return probe
  272.         # disable monitor report
  273.         probe = probe + "\n"
  274.  
  275.         if self.monName:
  276.             probe = probe + _("Monitor") + ": " + self.monName + "\n"
  277.         elif self.monEisa:
  278.             probe = probe + _("Monitor") + ": " + _("Plug and Play Monitor") + "\n"
  279.         if self.monHoriz:
  280.             probe = probe + "\t" + _("Horizontal frequency range") + ": " + self.monHoriz + " kHz\n"
  281.         if self.monHoriz:
  282.             probe = probe + "\t" + _("Vertical frequency range") + ": " + self.monVert + " Hz\n"
  283.  
  284.         return probe
  285.  
  286.     def write (self, path):
  287.         config = open (path, 'w')
  288.         config.write (self.preludeSection ())
  289.         config.write (self.keyboardSection ())
  290.     if not self.server or self.server[0:3] != 'Sun':
  291.         config.write (self.mouseSection ())
  292.         config.write (self.monitorSection ())
  293.         config.write (self.deviceSection ())
  294.         config.write (self.screenSection ())
  295.         config.close ()
  296.  
  297.     def test (self):
  298.         config = open ('/tmp/XF86Config.test', 'w')
  299.         config.write (
  300. """
  301. Section "Files"
  302.     RgbPath    "/usr/X11R6/lib/X11/rgb"
  303.     FontPath    "/usr/X11R6/lib/X11/fonts/misc/"
  304.     FontPath    "/usr/X11R6/lib/X11/fonts/Type1/"
  305.     FontPath    "/usr/X11R6/lib/X11/fonts/Speedo/"
  306.     FontPath    "/usr/X11R6/lib/X11/fonts/75dpi/"
  307.     FontPath    "/usr/X11R6/lib/X11/fonts/100dpi/"
  308.     FontPath    "/usr/X11R6/lib/X11/fonts/cyrillic/"
  309.     FontPath    "/usr/share/fonts/ISO8859-2/misc/"
  310.     FontPath    "/usr/share/fonts/ISO8859-2/75dpi/"
  311.     FontPath    "/usr/share/fonts/ISO8859-2/100dpi/"
  312.     FontPath    "/usr/share/fonts/ISO8859-9/misc/"
  313.     FontPath    "/usr/share/fonts/ISO8859-9/75dpi/"
  314.     FontPath    "/usr/share/fonts/ISO8859-9/100dpi/"
  315. EndSection
  316.  
  317. Section "ServerFlags"
  318. EndSection
  319. """)
  320.         config.write (self.keyboardSection ())
  321.         # XXX if we're going to be using IMPS/2 on
  322.         # reboot, but we're using PS/2 now, we'll need
  323.         # to temporarily use PS/2 so we don't frob the
  324.         # intellimouse into IMPS/2 mode (if we did, we'll
  325.         # loose the mouse cursor in the install)
  326.         if self.mouse.info["XMOUSETYPE"] == "IMPS/2":
  327.             mouseproto = "PS/2"
  328.         else:
  329.             mouseproto = self.mouse.info["XMOUSETYPE"]
  330.         config.write (
  331. """
  332. Section "Pointer"
  333.     Protocol    "%s"
  334.     Device      "/dev/%s"
  335.     Emulate3Buttons
  336.     Emulate3Timeout    50
  337. EndSection
  338. """ % (mouseproto, self.mouse.device))
  339.         config.write (self.monitorSection ())
  340.         config.write (self.deviceSection ())
  341.         config.write (self.screenSection ())
  342.         config.close ()
  343.  
  344.         serverPath = "/usr/X11R6/bin/XF86_" + self.server
  345.  
  346.         server = os.fork()
  347.         if (not server):
  348.             os.execv(serverPath, ["XF86-test", ':9', '-xf86config', 
  349.                                   '/tmp/XF86Config.test', 'vt6'])
  350.             
  351.         time.sleep (1)
  352. ##         pid, status = os.waitpid (server, os.WNOHANG)
  353. ##         if not pid:
  354. ##             raise RuntimeError, "X server failed to start"
  355.  
  356.         child = os.fork()
  357.         if (not child):
  358.             os.environ["DISPLAY"] = ":9"
  359.             os.execv("/usr/X11R6/bin/Xtest", ["Xtest", "--nostart", "--norunlevel"])
  360.         else:
  361.             pid, status = os.waitpid(child, 0)
  362.             os.kill (server, 15)
  363.             os.waitpid(server, 0)
  364.             if not os.WIFEXITED (status) or os.WEXITSTATUS (status):
  365.                 if os.WEXITSTATUS (status) not in [ 0, 1, 2 ]:
  366.                     raise RuntimeError, "X test failed %d" % (status,)
  367.             return
  368.  
  369.     def preludeSection (self):
  370.         return """
  371. # File generated by anaconda.
  372.  
  373. # **********************************************************************
  374. # Refer to the XF86Config(4/5) man page for details about the format of 
  375. # this file.
  376. # **********************************************************************
  377.  
  378. # **********************************************************************
  379. # Files section.  This allows default font and rgb paths to be set
  380. # **********************************************************************
  381.  
  382. Section "Files"
  383.  
  384. # The location of the RGB database.  Note, this is the name of the
  385. # file minus the extension (like ".txt" or ".db").  There is normally
  386. # no need to change the default.
  387.  
  388.     RgbPath    "/usr/X11R6/lib/X11/rgb"
  389.  
  390. # Multiple FontPath entries are allowed (they are concatenated together)
  391. # By default, Red Hat 6.0 and later now use a font server independent of
  392. # the X server to render fonts.
  393.  
  394.     FontPath   "/usr/X11R6/lib/X11/fonts/TrueType"
  395.     FontPath   "unix/:-1"
  396.  
  397. EndSection
  398.  
  399. # **********************************************************************
  400. # Server flags section.
  401. # **********************************************************************
  402.  
  403. Section "ServerFlags"
  404.     # Uncomment this to cause a core dump at the spot where a signal is 
  405.     # received.  This may leave the console in an unusable state, but may
  406.     # provide a better stack trace in the core dump to aid in debugging
  407.  
  408.     # NoTrapSignals
  409.  
  410.     # Uncomment this to disable the <Crtl><Alt><BS> server abort sequence
  411.     # This allows clients to receive this key event.
  412.  
  413.     # DontZap
  414.  
  415.     # Uncomment this to disable the <Crtl><Alt><KP_+>/<KP_-> mode switching
  416.     # sequences.  This allows clients to receive these key events.
  417.  
  418.     # DontZoom
  419. EndSection
  420. """
  421.  
  422.     def mouseSection (self):
  423.         if not self.mouse:
  424.             self.mouse = Mouse(mouseType = ("none", "none", "null"))
  425.         return """
  426. # **********************************************************************
  427. # Pointer section
  428. # **********************************************************************
  429.  
  430. Section "Pointer"
  431.     Protocol    "%(XMOUSETYPE)s"
  432.     Device      "/dev/mouse"
  433.  
  434. # When using XQUEUE, comment out the above two lines, and uncomment
  435. # the following line.
  436. #    Protocol    "Xqueue"
  437.  
  438. # Baudrate and SampleRate are only for some Logitech mice
  439. #    BaudRate    9600
  440. #    SampleRate    150
  441.  
  442. # Emulate3Buttons is an option for 2-button Microsoft mice
  443. # Emulate3Timeout is the timeout in milliseconds (default is 50ms)
  444.     Emulate3Buttons
  445.     Emulate3Timeout    50
  446.  
  447. # ChordMiddle is an option for some 3-button Logitech mice
  448. #    ChordMiddle
  449.  
  450. EndSection
  451. """ % self.mouse.info
  452.  
  453.     def keyboardSection (self):
  454.     autorepeat = "AutoRepeat  500 5"
  455.     if iutil.getArch() == "sparc":
  456.         autorepeat = "# AutoRepeat  200 20"
  457.         string = """
  458. # **********************************************************************
  459. # Keyboard section
  460. # **********************************************************************
  461.  
  462. Section "Keyboard"
  463.     Protocol    "Standard"
  464.  
  465.     # when using XQUEUE, comment out the above line, and uncomment the
  466.     # following line
  467.     # Protocol   "Xqueue"
  468.  
  469.     %s
  470.  
  471.     # Let the server do the NumLock processing.  This should only be 
  472.     # required when using pre-R6 clients
  473.     # ServerNumLock
  474.  
  475.     # Specify which keyboard LEDs can be user-controlled (eg, with xset(1))
  476.     # Xleds      1 2 3
  477.  
  478.     # To set the LeftAlt to Meta, RightAlt key to ModeShift, 
  479.     # RightCtl key to Compose, and ScrollLock key to ModeLock:
  480.  
  481.     LeftAlt         Meta
  482.     RightAlt        Meta
  483.     ScrollLock      Compose
  484.     RightCtl        Control
  485.  
  486. # To disable the XKEYBOARD extension, uncomment XkbDisable.
  487. #    XkbDisable
  488.  
  489. # To customise the XKB settings to suit your keyboard, modify the
  490. # lines below (which are the defaults).  For example, for a non-U.S.
  491. # keyboard, you will probably want to use:
  492. #    XkbModel    "pc102"
  493. # If you have a US Microsoft Natural keyboard, you can use:
  494. #    XkbModel    "microsoft"
  495. #
  496. # Then to change the language, change the Layout setting.
  497. # For example, a german layout can be obtained with:
  498. #    XkbLayout   "de"
  499. # or:
  500. #    XkbLayout   "de"
  501. #    XkbVariant  "nodeadkeys"
  502. #
  503. # If you'd like to switch the positions of your capslock and
  504. # control keys, use:
  505. #    XkbOptions  "ctrl:nocaps"
  506. """ % autorepeat
  507.         for (tag, value) in (("XkbRules", self.keyRules),
  508.                              ("XkbModel", self.keyModel),
  509.                              ("XkbLayout", self.keyLayout),
  510.                              ("XkbVariant", self.keyVariant),
  511.                              ("XkbOptions", self.keyOptions)):
  512.             if value:
  513.                 string = string + '    %s    "%s"\n' % (tag, value)
  514.         string = string + "EndSection\n"
  515.         return string
  516.         
  517.     def monitorSection (self, installer = 0):
  518.     if installer and self.monSect:
  519.         return self.monSect
  520.  
  521.         info = {}
  522.         
  523.         if self.monEisa:
  524.             info["EISA"] = self.monEisa
  525.         elif self.monID:
  526.             info["EISA"] = self.monID
  527.         else:
  528.             info["EISA"] = "Generic Monitor"
  529.  
  530.         self.monID = info["EISA"]
  531.  
  532.         if self.monVert:
  533.             info["VERT"] = self.monVert
  534.         else:
  535.             info["VERT"] = "60"
  536.  
  537.         if self.monHoriz:
  538.             info["HORIZ"] = self.monHoriz
  539.         else:
  540.             info["HORIZ"] = "31.5"
  541.         
  542.         return """
  543. # **********************************************************************
  544. # Monitor section
  545. # **********************************************************************
  546.  
  547. # Any number of monitor sections may be present
  548. Section "Monitor"
  549.     Identifier  "Generic Monitor"
  550.     VendorName  "Unknown"
  551.     ModelName   "Unknown"
  552.     HorizSync   31.5
  553.     VertRefresh 60
  554.     ModeLine  "640x480"   25.175  640 664 760 800
  555.                                   480 491 493 525
  556. EndSection
  557.  
  558. Section "Monitor"
  559.  
  560.     Identifier  "%(EISA)s"
  561.     VendorName  "Unknown"
  562.     ModelName   "Unknown"
  563.  
  564. # HorizSync is in kHz unless units are specified.
  565. # HorizSync may be a comma separated list of discrete values, or a
  566. # comma separated list of ranges of values.
  567. # NOTE: THE VALUES HERE ARE EXAMPLES ONLY.  REFER TO YOUR MONITOR'S
  568. # USER MANUAL FOR THE CORRECT NUMBERS.
  569.  
  570.     HorizSync   %(HORIZ)s
  571.  
  572. # VertRefresh is in Hz unless units are specified.
  573. # VertRefresh may be a comma separated list of discrete values, or a
  574. # comma separated list of ranges of values.
  575. # NOTE: THE VALUES HERE ARE EXAMPLES ONLY.  REFER TO YOUR MONITOR'S
  576. # USER MANUAL FOR THE CORRECT NUMBERS.
  577.  
  578.     VertRefresh %(VERT)s
  579.  
  580. # Modes can be specified in two formats.  A compact one-line format, or
  581. # a multi-line format.
  582.  
  583. # These two are equivalent
  584.  
  585. #    ModeLine "1024x768i" 45 1024 1048 1208 1264 768 776 784 817 Interlace
  586.  
  587. #    Mode "1024x768i"
  588. #        DotClock    45
  589. #        HTimings    1024 1048 1208 1264
  590. #        VTimings    768 776 784 817
  591. #        Flags        "Interlace"
  592. #    EndMode
  593.  
  594. # This is a set of standard mode timings. Modes that are out of monitor spec
  595. # are automatically deleted by the server (provided the HorizSync and
  596. # VertRefresh lines are correct), so there's no immediate need to
  597. # delete mode timings (unless particular mode timings don't work on your
  598. # monitor). With these modes, the best standard mode that your monitor
  599. # and video card can support for a given resolution is automatically
  600. # used.
  601.  
  602. # Low-res Doublescan modes
  603. # If your chipset does not support doublescan, you get a 'squashed'
  604. # resolution like 320x400.
  605.  
  606. # --320x200--
  607. # 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio
  608.     Modeline "320x200"     12.588 320  336  384  400
  609.                                   200  204  205  225 Doublescan
  610. # 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio
  611.     Modeline "320x240"     12.588 320  336  384  400
  612.                                   240  245  246  262 Doublescan
  613. # 320x240 @ 72 Hz, 36.5 kHz hsync
  614.     Modeline "320x240"     15.750 320  336  384  400
  615.                                   240  244  246  262 Doublescan
  616. # --400x300--
  617. # 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio
  618.     ModeLine "400x300"     18     400  416  448  512
  619.                                   300  301  302  312 Doublescan
  620. # 400x300 @ 60 Hz, 37.8 kHz hsync
  621.     Modeline "400x300"     20     400  416  480  528
  622.                                   300  301  303  314 Doublescan
  623. # 400x300 @ 72 Hz, 48.0 kHz hsync
  624.     Modeline "400x300"     25     400  424  488  520
  625.                                   300  319  322  333 Doublescan
  626. # 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio
  627.     ModeLine "480x300"     21.656 480  496  536  616
  628.                                   300  301  302  312 Doublescan
  629. # 480x300 @ 60 Hz, 37.8 kHz hsync
  630.     Modeline "480x300"     23.890 480  496  576  632
  631.                                   300  301  303  314 Doublescan
  632. # 480x300 @ 63 Hz, 39.6 kHz hsync
  633.     Modeline "480x300"     25     480  496  576  632
  634.                                   300  301  303  314 Doublescan
  635. # 480x300 @ 72 Hz, 48.0 kHz hsync
  636.     Modeline "480x300"     29.952 480  504  584  624
  637.                                   300  319  322  333 Doublescan
  638.  
  639. # Normal video modes
  640.  
  641. # -- 512x384
  642. # 512x384 @ 78 Hz, 31.50 kHz hsync
  643.     Modeline "512x384"    20.160 512  528  592  640
  644.                                  384  385  388  404 -HSync -VSync
  645. # 512x384 @ 85 Hz, 34.38 kHz hsync
  646.     Modeline "512x384"    22     512  528  592  640
  647.                                  384  385  388  404 -HSync -VSync
  648.  
  649. # -- 640x400 --
  650. # 640x400 @ 70 Hz, 31.5 kHz hsync
  651.     Modeline "640x400"     25.175 640  664  760  800
  652.                                   400  409  411  450
  653. # 640x400 @ 85 Hz, 37.86 kHz hsync
  654.     Modeline "640x400"     31.5   640  672 736   832
  655.                                   400  401  404  445 -HSync +VSync
  656.  
  657. # --- 640x480 ---
  658. # 640x480 @ 60 Hz, 31.5 kHz hsync
  659.     Modeline "640x480"     25.175 640  664  760  800
  660.                                   480  491  493  525
  661. # 640x480 @ 72 Hz, 36.5 kHz hsync
  662.     Modeline "640x480"     31.5   640  680  720  864
  663.                                   480  488  491  521
  664. # 640x480 @ 75 Hz, 37.50 kHz hsync
  665.     ModeLine  "640x480"    31.5   640  656  720  840
  666.                                   480  481  484  500 -HSync -VSync
  667. # 640x480 @ 85 Hz, 43.27 kHz hsync
  668.     Modeline "640x480"     36     640  696  752  832
  669.                                   480  481  484  509 -HSync -VSync
  670. # 640x480 @ 100 Hz, 53.01 kHz hsync
  671.     Modeline "640x480"     45.8   640  672  768  864
  672.                                   480  488  494  530 -HSync -VSync
  673.  
  674. # --- 800x600 ---
  675. # 800x600 @ 56 Hz, 35.15 kHz hsync
  676.     ModeLine "800x600"     36     800  824  896 1024
  677.                                   600  601  603  625
  678. # 800x600 @ 60 Hz, 37.8 kHz hsync
  679.     Modeline "800x600"     40     800  840  968 1056
  680.                                   600  601  605  628 +hsync +vsync
  681. # 800x600 @ 72 Hz, 48.0 kHz hsync
  682.     Modeline "800x600"     50     800  856  976 1040
  683.                                   600  637  643  666 +hsync +vsync
  684. # 800x600 @ 85 Hz, 55.84 kHz hsync
  685.     Modeline  "800x600"    60.75  800  864  928 1088
  686.                                   600  616  621  657 -HSync -VSync
  687. # 800x600 @ 100 Hz, 64.02 kHz hsync
  688.     Modeline  "800x600"    69.65  800  864  928 1088
  689.                                   600  604  610  640 -HSync -VSync
  690.  
  691. # --- 1024x768 ---
  692. # 1024x768 @ 60 Hz, 48.4 kHz hsync
  693.     Modeline "1024x768"    65    1024 1032 1176 1344
  694.                                  768  771  777  806 -hsync -vsync
  695. # 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync
  696.     Modeline "1024x768"    44.9  1024 1048 1208 1264
  697.                                  768  776  784  817 Interlace
  698. # 1024x768 @ 70 Hz, 56.5 kHz hsync
  699.     Modeline "1024x768"    75    1024 1048 1184 1328
  700.                                  768  771  777  806 -hsync -vsync
  701. # 1024x768 @ 76 Hz, 62.5 kHz hsync
  702.     Modeline "1024x768"    85    1024 1032 1152 1360
  703.                                  768  784  787  823
  704. # 1024x768 @ 85 Hz, 70.24 kHz hsync
  705.     Modeline "1024x768"   98.9  1024 1056 1216 1408
  706.                                 768 782 788 822 -HSync -VSync
  707. # 1024x768 @ 100Hz, 80.21 kHz hsync
  708.     Modeline "1024x768"   115.5  1024 1056 1248 1440
  709.                                  768  771  781  802 -HSync -VSync
  710.  
  711. # --- 1152x864 ---
  712. # 1152x864 @ 60 Hz, 53.5 kHz hsync
  713.     Modeline  "1152x864"   89.9  1152 1216 1472 1680
  714.                                  864  868  876  892 -HSync -VSync
  715. # 1152x864 @ 70 Hz, 62.4 kHz hsync
  716.     Modeline  "1152x864"   92    1152 1208 1368 1474
  717.                                  864  865  875  895
  718. # 1152x864 @ 78 Hz, 70.8 kHz hsync
  719.     Modeline "1152x864"   110   1152 1240 1324 1552
  720.                                 864  864  876  908
  721. # 1152x864 @ 84 Hz, 76.0 kHz hsync
  722.     Modeline "1152x864"   135    1152 1464 1592 1776
  723.                                  864  864  876  908
  724. # 1152x864 @ 89 Hz interlaced, 44 kHz hsync
  725.     ModeLine "1152x864"    65    1152 1168 1384 1480
  726.                                  864  865  875  985 Interlace
  727. # 1152x864 @ 100 Hz, 89.62 kHz hsync
  728.     Modeline "1152x864"   137.65 1152 1184 1312 1536
  729.                                  864  866  885  902 -HSync -VSync
  730.  
  731. # -- 1280x1024 --
  732. # 1280x1024 @ 61 Hz, 64.2 kHz hsync
  733.     Modeline "1280x1024"  110    1280 1328 1512 1712
  734.                                  1024 1025 1028 1054
  735. # 1280x1024 @ 70 Hz, 74.59 kHz hsync
  736.     Modeline "1280x1024"  126.5 1280 1312 1472 1696
  737.                                 1024 1032 1040 1068 -HSync -VSync
  738. # 1280x1024 @ 74 Hz, 78.85 kHz hsync
  739.     Modeline "1280x1024"  135    1280 1312 1456 1712
  740.                                  1024 1027 1030 1064
  741. # 1280x1024 @ 76 Hz, 81.13 kHz hsync
  742.     Modeline "1280x1024"  135    1280 1312 1416 1664
  743.                                  1024 1027 1030 1064
  744. # 1280x1024 @ 85 Hz, 91.15 kHz hsync
  745.     Modeline "1280x1024"  157.5  1280 1344 1504 1728
  746.                                  1024 1025 1028 1072 +HSync +VSync
  747. # 1280x1024 @ 87 Hz interlaced, 51 kHz hsync
  748.     Modeline "1280x1024"   80    1280 1296 1512 1568
  749.                                  1024 1025 1037 1165 Interlace
  750. # 1280x1024 @ 100 Hz, 107.16 kHz hsync
  751.     Modeline "1280x1024"  181.75 1280 1312 1440 1696
  752.                                  1024 1031 1046 1072 -HSync -VSync
  753.  
  754. # -- 1600x1200 --
  755. # 1600x1200 @ 60Hz, 75.00 kHz hsync
  756.     Modeline "1600x1200"  162   1600 1664 1856 2160
  757.                                 1200 1201 1204 1250 +HSync +VSync
  758. # 1600x1200 @ 70 Hz, 87.50 kHz hsync
  759.     Modeline "1600x1200"  189    1600 1664 1856 2160
  760.                                  1200 1201 1204 1250 -HSync -VSync
  761. # 1600x1200 @ 75 Hz, 93.75 kHz hsync
  762.     Modeline "1600x1200"  202.5  1600 1664 1856 2160
  763.                                  1200 1201 1204 1250 +HSync +VSync
  764. # 1600x1200 @ 85 Hz, 105.77 kHz hsync
  765.     Modeline "1600x1200"  220    1600 1616 1808 2080
  766.                                  1200 1204 1207 1244 +HSync +VSync
  767.  
  768. # -- 1800x1400 -- 
  769.  
  770. # 1800x1440 @ 64Hz, 96.15 kHz hsync 
  771.     ModeLine "1800X1440"  230    1800 1896 2088 2392
  772.                                  1440 1441 1444 1490 +HSync +VSync
  773. # 1800x1440 @ 70Hz, 104.52 kHz hsync 
  774.     ModeLine "1800X1440"  250    1800 1896 2088 2392
  775.                                  1440 1441 1444 1490 +HSync +VSync
  776.  
  777. # -- 1920x1200 --
  778.  
  779. # 1920x1200 @ 70Hz, 87.50 KHz hsync
  780.     Modeline "1920x1200"  230    1920 1936 2096 2528
  781.                                  1200 1201 1204 1250 +HSync +VSync
  782.  
  783. EndSection
  784. """ % info
  785.  
  786.     def deviceSection (self):
  787.         section = """
  788. # **********************************************************************
  789. # Graphics device section
  790. # **********************************************************************
  791.  
  792. Section "Device"
  793.     Identifier        "Generic VGA Card"
  794.     VendorName        "Unknown"
  795.     BoardName         "Unknown"
  796.     Chipset           "generic"
  797. EndSection
  798.  
  799. """
  800.         for card in self.vidCards:
  801.             section = section + """
  802. Section "Device"
  803.     Identifier         "%(NAME)s"
  804. """ % card
  805.             if card.has_key ("VENDOR"):
  806.                 section = section + '    VendorName         "%(VENDOR)s"\n' % card
  807.             if card.has_key ("BOARDNAME"):
  808.                 section = section + '    BoardName          "%(BOARD)s"\n' % card
  809.             if card.has_key ("RAMDAC"):
  810.                 section = section + '    Ramdac             "%(RAMDAC)s"\n' % card
  811.             if card.has_key ("LINE"):
  812.                 section = section + card["LINE"] + "\n"
  813.             if self.vidRam:
  814.                 section = section + '    VideoRam           %s\n' % (self.vidRam,) 
  815.             section = section + "EndSection\n"
  816.         return section
  817.  
  818.     def screenSection (self, installer = 0):
  819.     if installer and self.monSect:
  820.         monID = "Probed Monitor"
  821.     else:
  822.         monID = self.monID
  823.         if not monID:
  824.             monID = "Generic Monitor"
  825.             
  826.         info = { "DEVICE"  : self.devID,
  827.                  "MONITOR" : monID }
  828.  
  829.         maxdepth = -1
  830.         for (depth, modes) in self.modes.items ():
  831.             modes.sort (self.areaCompare)
  832.             if len(modes) > 0 and string.atoi(depth) > maxdepth:
  833.                 maxdepth = string.atoi(depth)
  834.         
  835.         section = """
  836. # **********************************************************************
  837. # Screen section
  838. # **********************************************************************
  839.  
  840. # The kernel framebuffer server
  841. Section "Screen"
  842.     Driver      "fbdev"
  843.     Device      "Generic VGA Card"
  844.     Monitor     "%(MONITOR)s"
  845.     Subsection  "Display"
  846. #        Depth       16
  847.         Modes       "default"
  848.     EndSubsection
  849. EndSection
  850.  
  851. # The 16-color VGA server
  852. Section "Screen"
  853.     Driver      "vga16"
  854.     Device      "Generic VGA Card"
  855.     Monitor     "%(MONITOR)s"
  856.     Subsection "Display"
  857.         Modes       "640x480" "800x600"
  858.         ViewPort    0 0
  859.     EndSubsection
  860. EndSection
  861.  
  862. # The Mono server
  863. Section "Screen"
  864.     Driver      "vga2"
  865.     Device      "Generic VGA Card"
  866.     Monitor     "%(MONITOR)s"
  867.     Subsection "Display"
  868.         Modes       "640x480" "800x600"
  869.         ViewPort    0 0
  870.     EndSubsection
  871. EndSection
  872. """ % info
  873.         if self.devID:
  874.             for driver in [ "svga", "accel" ]:
  875.                 info["DRIVER"] = driver
  876.                 section = section + """
  877. # The %(DRIVER)s server
  878. Section "Screen"
  879.     Driver      "%(DRIVER)s"
  880.     Device      "%(DEVICE)s"
  881.     Monitor     "%(MONITOR)s"
  882. """ % info
  883.                 if maxdepth > 0:
  884.                     section = section + "    DefaultColorDepth %d\n" % maxdepth
  885.                 for depth in self.modes.keys ():
  886.                     if not self.modes[depth]: continue
  887.                     section = section + """
  888.     Subsection "Display"
  889.         Depth       %s
  890.         Modes       """ % depth
  891.                     for res in self.modes[depth]:
  892.                         section = section + '"' + res + '" '
  893.                     section = section + """
  894.         ViewPort    0 0
  895.     EndSubsection
  896. """
  897.                 section = section + "EndSection\n"
  898.         return section
  899.  
  900. if __name__ == "__main__":
  901.     sys.path.append ("kudzu")
  902.     x = XF86Config ()
  903.     print x.cards ("ATI Mach64 3D RAGE II")
  904.     x.probe ()
  905. #    sys.exit (0)
  906.     x.filterModesByMemory ()
  907.     print x.preludeSection ()
  908.     print x.keyboardSection ()
  909.     print x.mouseSection ()
  910.     print x.monitorSection ()
  911.     print x.deviceSection ()
  912. #    x.modes["8"] = [ "640x480" ]
  913. #    x.modes["16"] = [ "640x480" ]
  914. #    x.modes["32"] = [ "640x480" ]
  915.     print x.screenSection ()
  916.